home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / mail / mh / contrib / audit / README < prev    next >
Internet Message Format  |  1992-11-19  |  12KB

  1. Date:    Mon, 1 Jun 1992 20:00:07 GMT
  2. Subject: Mail auditing + more package
  3. From:    Martin Streicher <strike@convex.COM>
  4.  
  5. I am changing jobs, so this will be the final release of my audit
  6. package until I get a new UNIX account established. There are
  7. several little bugs fixed in this release that should fix
  8. lots of parsing problems - other than that, this package seems very solid
  9. and I have gotten good feedback on the usefulness of the package.
  10.  
  11. Enjoy...
  12.  
  13. The audit.pl package. 
  14. =====================
  15.  
  16. What this package does:
  17. =======================
  18. This package provides routines that parse an incoming mail message, divide
  19. it into a header and the body of the message and further decompose
  20. the mail header into its fields. The routines set variables that you
  21. can query and parse in your own PERL script to determine what to do with
  22. the incoming mail message.
  23.  
  24. To use the package, insert the following two PERL instructions to the very
  25. TOP of your PERL script:
  26.  
  27. require '/gmaster/home/strike/work/perl/deliver/audit.pl' || 
  28.         die "deliver: cannot include audit.pl: $@";
  29.  
  30. &initialize();
  31.  
  32.  
  33. Variables that &initialize() sets:
  34. ---------------------------------
  35. The routine &initialize() reads the incoming mail message and sets
  36. the following variables:
  37.  
  38. $sender        This is the sender shown on the "From " line.
  39.  
  40. %headers    An associative array containing the lines in the mail
  41.         header. $header{'Subject'} contains the Subject: line;
  42.         $header{'Date'} contains Date:, etc. 
  43.         
  44.         If the To: or Cc: line appeared more than once in the header,
  45.         those lines are concatenated together into a single
  46.         comma-separated list of names. Other header lines that
  47.         appear twice are clobbered.
  48.  
  49. There are also many variables and arrays set for your convenience if you
  50. dont want to parse the entries of %headers yourself.
  51.  
  52. $subject    The Subject: line.
  53.  
  54. $precedence    The Precedence: line.
  55.  
  56. $friendly    The friendly (human) name of the sender
  57.         (e.g., Martin Streicher)
  58.  
  59. $address    The email address of the sender 
  60.         (e.g., strike@pixel.convex.com)
  61.  
  62. $from        The login name of the sender with all addressing stripped. For
  63.         example, if $address was strike@pixel.convex.com, $from
  64.         is strike.
  65.  
  66. $organization    The name of the sender's organization. This is derived from
  67.         $address; for example strike@pixel.convex.com yields convex;
  68.         wizard!jim@uunet.uu.net yields wizard; jane@mach.site.co.uk
  69.         yields site.
  70.  
  71. @to        The list of names on the To: line(s). Note that the 
  72.         name listed on the Apparently-To: line also appears in @to.
  73.  
  74. @cc        The list of names on the Cc: line(s).
  75.  
  76. @received    The list of received headers in the mail message that
  77.         show the path the message traveled to be delivered.
  78.  
  79.  
  80. Routines that audit.pl provides:
  81. --------------------------------
  82. The package offers some canned routines for handling the incoming
  83. mail message:
  84.  
  85. &deliver()    Deliver the incoming mail message. &deliver() appends
  86.         the incoming mail message to the end of your UNIX mail
  87.         drop /usr/spool/mail/<user>, where <user> is the name
  88.         specified in the .forward file. 
  89.  
  90. &vacation()    Reply automatically to the sender if you have a vacation 
  91.         message in $HOME/.vacation.msg. If you do not have this
  92.         file, this routine does absolutely nothing. If you have
  93.         a .vacation.msg file, &vacation sends the sender of the
  94.         message an automatic reply containing that file.
  95.  
  96.         This routine also records who you sent 
  97.         vacation mail to; it will not send duplicate vacation messages
  98.         to the same person.  If you change your vacation message, the 
  99.         list is zeroed. The list of people you sent vacation mail to
  100.         is kept in $HOME/.vacation.log. 
  101.  
  102.         Some notes about &vacation():
  103.             - It will send you vacation mail. This is useful
  104.               to test your vacation message out.
  105.  
  106.             - It will not send vacation mail to anyone named
  107.               root, mailer-daemon, postmaster, daemon or mailer.
  108.               This are not considered to be real users.
  109.  
  110.             - It will not respond to mail that is labelled
  111.               with precendence bulk or junk.
  112.  
  113. &file_from() or 
  114. &file_from($dir)
  115.         This routine files the incoming mail message
  116.         in a hierarchy of mail folders. The top-level of the
  117.         hierarchy is specified in $dir; by default (if no
  118.         directory is specified) it is $HOME/log. The next level
  119.         of the hierachy is sorted by $organization; below this level
  120.         mail is sorted by the sender's login name.
  121.  
  122.         For example, say you receive a message from 
  123.         strike@pixel.convex.com; if you call &file_from(),
  124.         the corresponsing mail message will be filed into a mail
  125.         folder called $HOME/log/convex/strike. All mail sent to you
  126.         by strike@pixel.convex.com would be filed in this mail folder.
  127.  
  128.         You can &file_from to file all correspondence for future
  129.         reference.
  130.  
  131. &openpipe($command)
  132.         You can also use your own commands (scripts/programs)
  133.         to process an incoming mail message. &openpipe($command)
  134.         opens a PERL pipe to $command and pipes the mail message
  135.         to that command.
  136.  
  137. You can use none, one or all of these routines. You can also repeat
  138. and combine all of these functions to do more than one thing with a piece of 
  139. incoming mail (you probably only want to &deliver() the message once though).
  140.  
  141. For example, say you get a message from strike@pixel.convex.com. You want 
  142. to file the message away for auditing purposes, save the mail message in your 
  143. mail drop and send some vacation mail if you are gone. Use the &file_from(), 
  144. &deliver() and &vacation() functions to do all of these things to one message.
  145.  
  146. WARNING: IF YOU EXIT FROM THE PERL SCRIPT WITHOUT DOING SOMETHING
  147.      WITH THE MAIL MESSAGE, IT IS LOST FOREVER.
  148.  
  149. Actually, exiting the PERL script can be an effective way of dropping
  150. unwanted mail messages. See the example below.
  151.  
  152.  
  153. Other convenience functions for MH users:
  154. -----------------------------------------
  155. If you use MH, other convenience routines are provided to 
  156. pipe the incoming mail message to rcvstore, rcvdist and/or rcvtty.
  157. There is also a special refile routine to file incoming mail messages
  158. in folders according to the sender's organization and login. 
  159.  
  160. To access the MH functions, add the following line to the TOP of your script:
  161.  
  162. require '/gmaster/home/strike/work/perl/deliver/mh.pl' || 
  163.         die "deliver: cannot include mh.pl: $@";
  164.  
  165. This file provides the following functions:
  166.  
  167. &rcvstore($folder)    
  168.         Pipe the incoming mail message to rcvstore; the $folder
  169.         argument is the name of the folder to store the message
  170.         into.    
  171.  
  172. &rcvtty()    Pipe the incoming mail message to rcvtty. rcvtty
  173.         is MH's equivalent to biff and its output can be tailored
  174.         exactly like you can customize scan or inc. 
  175.  
  176. &rcvdist($names)
  177.         Pipe the incoming mail message to rcvdist. $names
  178.         is a blank separated list of names to send the
  179.         message to. You can use the &ali() command (see below)
  180.         to expand MH aliases.
  181.  
  182. &ali($alias)    Expand the MH alias name in $alias to the list
  183.         of addresses it stands for. Unlink all the other routines,
  184.         this routine returns an array of names, where
  185.         each element is an addressee on the alias.
  186.  
  187. &refile_from() or
  188. &refile_from($dir)
  189.         File a copy of the incoming mail message into a hierarchy of
  190.         MH folders. The top-level directory is "log" by default unless
  191.         you specify another folder (all this below you Mailpath folder,
  192.         of course). The next level is sorted by organization name
  193.         and the level below that is sorted by sender's login name.
  194.  
  195.  
  196.  
  197. Writing a PERL mail auditing script:
  198. ====================================
  199. The best way to show what all this can do is with a specific example. Here 
  200. is my script (with comments!):
  201.  
  202. ------ script starts here -------
  203. #! /usr/local/bin/perl
  204.  
  205. require '/gmaster/home/strike/work/perl/deliver/audit.pl' || 
  206.         die "deliver: cannot include audit.pl: $@";
  207.  
  208. require '/gmaster/home/strike/work/perl/deliver/mh.pl' || 
  209.         die "deliver: cannot include mh.pl: $@";
  210.  
  211. &initialize();
  212.  
  213.  
  214. # -----
  215. # My mail processing starts here
  216. #
  217.  
  218. # If this message came from the MAILER, deliver it to me directly
  219. # and do nothing else.
  220. #
  221. ($from =~ /MAILER/) && do { &deliver(); exit; };
  222.  
  223. # If this message is sent to xpixel (either To or Cc, deliver
  224. # the messsage to me and exit.
  225. #
  226. (grep(/^xpixel/, @to, @cc)) && do { &deliver(); exit; };
  227.  
  228. # If the message is from a place called "lupine", this
  229. # is really NCD.
  230. #
  231. $organization = "ncd" if ($organization eq "lupine");
  232.  
  233. # If the sender's name is in the password file, the organization
  234. # is CONVEX.
  235. #
  236. $organization = "convex" if ($logname = (getpwnam($from))[0]);
  237.  
  238. # If I am specifically named on the To or Cc line, do the default.
  239. # The routine &default is below: it delivers the message, refiles
  240. # it in an MH folder, sends vacation mail if I am gone, and
  241. # biffs me if I am logged in somewhere.
  242. #
  243. (grep(/^strike/, @to, @cc)) && do { 
  244.     &default();
  245.     exit;
  246. };
  247.  
  248. # If the mail message went to x<hostname> where hostname
  249. # is in our /etc/hosts, trash the message (JUST EXIT TO DROP
  250. # THE MESSAGE)
  251. #
  252. exit if (grep((/^x(.*)/ && (@n = gethostbyname($1))), @to, @cc));
  253.  
  254. # Throw away anything to anyone or any alias named avs-updates
  255. #
  256. exit if (grep(($_ eq "avs-updates"), @to));
  257.  
  258. # Throw away junk mail from AVS, Inc.
  259. #
  260. if ($organization eq "avs") {
  261.     exit if ($subject =~ /^(Opened|Assigned) to/);
  262.     exit if ($subject =~ /^(Edited|Fixed|Killed) by/);
  263. };
  264.  
  265.  
  266. # If the mail message went to an X Consortium alias,
  267. # deliver it to me if it is advisory board mail. Otherwise,
  268. # refile it into an archive and redistribute it to anyone at CONVEX
  269. # that subscribes to it through me.
  270. #
  271. $xcons = 0;
  272. @consortium = (
  273.     '/^advisory/',    '/^blend/',        '/^bug-trackers/',
  274.     '/^color/',    '/^fix-trackers/',    '/^fontwork/',
  275.     '/^imagework/',    '/^xlib/',        '/intrinsics/',
  276.     '/^mltalk/',    '/^pex-si/',        '/^pex-spec/',
  277.     '/^protocol/',    '/^security/',        '/^shape/',        
  278.     '/^trackers/',    '/^transport/',        '/^wmtalk/',        
  279.     '/^xbuffer/',    '/^xc/',        '/^xinput/',            
  280.     '/^xtest/',    '/^consortium/',    '/^serialwork/',
  281.     '/^xie_/',    '/^mtserver/'
  282. );
  283.  
  284. foreach $list (@consortium) {
  285.     for (grep(eval $list, @to, @cc)) {
  286.        &deliver() if ($_ =~ "^advisory");
  287.        $xcons++;
  288.        &rcvstore("XConsortium/$_"); 
  289.        @dist = &ali("XConsortium-$_");
  290.        &rcvdist(join(' ', @dist)) if ((@dist)); 
  291.     };
  292. };
  293. exit if $xcons;
  294.  
  295.  
  296. # this mail was not sent to me directly, so dont answer with vacation mail,
  297. #
  298. &deliver();
  299. &rcvtty();
  300.  
  301. # All done!
  302. #
  303. exit;
  304.  
  305.  
  306. # =====
  307. # Subroutine default
  308. #     defaults specifies what to do when I want to accept a piece
  309. #    of mail. It is a convenience.
  310. sub default {
  311.  
  312.     &deliver();
  313.     &vacation();
  314.     &rcvtty();
  315.     &refile_from();
  316. }
  317.  
  318. ------ script ends ----------
  319.  
  320.  
  321. Testing
  322. ========
  323. If you want to test your PERL script, put the following in your .forward file:
  324.  
  325.     <login>, "| <homedir>/<script> <login>
  326.  
  327. where <login> is your UNIX login, <homedir> is the absolute path name
  328. to your home directory and <script> is the name of your PERL mail
  329. auditing script. If you put this in .forward, incoming mail messages
  330. will be directly sent to your mail drop AND will be piped through your
  331. PERL script. You may get duplicates of some mail, but this is the best
  332. way to see what your script is doing.
  333.  
  334. Once you are satisifed that your script works, simply replace your
  335. .forward file with:
  336.  
  337.     "| <homedir>/<script> <login>
  338.  
  339. Please note that if your script has syntax errors, the mailer will
  340. not drop your incoming mail; instead it will send you a the incoming
  341. mail message and a note indicating that an unknown mailer error occurred.
  342.  
  343. Another way to test your script:
  344. --------------------------------
  345. You can also test your script by piping a UNIX mail folder (like your 
  346. mail drop) directly into your script. For example, say you are having
  347. problems with mail from a certain sender or network alias; to debug your
  348. script, copy your incoming mail box in /usr/spool/mail to a local file
  349. and then pipe it to your script ala:
  350.  
  351.     cat mail | perl -d ~/.audit
  352.  
  353. You can then step through the script and see how the mail message
  354. is being parsed. You can add breakpoints, print statements, etc. and see
  355. the script operate on the mail. If you use &vacation() or &file_from(),
  356. you can watch those routines operate as well. The mail message is processed 
  357. as if it came directly to your script courtesy of the delivery system.
  358.